unit learninglistframeunit;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, StdCtrls, database, fpjson, LCLTranslator;

type

  { TLearningListFrame }

  TLearningListFrame = class(TFrame)
    DataListBox: TListBox;
    procedure DataListBoxDblClick(Sender: TObject);
  private
    Db: TDatabase;
    EditedLearnings: TJSONArray;
    function FormatLearning(Lrn: TJSONObject): String;
    procedure UpdateList;
    function NewItemSelected: Boolean;
    procedure AddNewLearning;
    procedure EditSelectedLearning;
  public
    procedure SetDatabase(ADb: TDatabase);
    procedure SetEditedLearnings(AEditedLearnings: TJSONArray);
  end;

resourcestring
  LearningWithNoteFmt = 'at lv. %0:d learn %1:s [%2:s]';
  LearningWithoutNoteFmt = 'at lv. %0:d learn %1:s';
  AddNewLearningStr = '<Add new skill to be learnt at some level>';

implementation

uses
  editlearningformunit;

{$R *.lfm}

{ TLearningListFrame }

procedure TLearningListFrame.DataListBoxDblClick(Sender: TObject);
begin
  if (DataListBox.ItemIndex < 0) or NewItemSelected then
    AddNewLearning
  else
    EditSelectedLearning
end;

function TLearningListFrame.FormatLearning(Lrn: TJSONObject): String;
var
  Level: Integer;
  SkillName: String;
  Note: String;
begin
  Level := Lrn.Integers['level'];
  SkillName := Db.GetSkillName(Lrn.Integers['skillId'], False);
  Note := Lrn.Strings['note'];

  if Note <> '' then
    FormatLearning := Format(LearningWithNoteFmt, [Level, SkillName, Note])
  else
    FormatLearning := Format(LearningWithoutNoteFmt, [Level, SkillName])
end;

procedure TLearningListFrame.UpdateList;
var
  I: Integer;
  Lrn: TJSONObject;
begin
  DataListBox.Items.BeginUpdate;

  DataListBox.Items.Clear;

  if (EditedLearnings = nil) or (Db = nil) then begin
    DataListBox.Items.EndUpdate;
    Exit;
  end;

  for I := 0 to EditedLearnings.Count -1 do begin
    Lrn := EditedLearnings.Objects[I];
    DataListBox.Items.Add(FormatLearning(Lrn));
  end;

  DataListBox.Items.Add(AddNewLearningStr);
  DataListBox.Items.EndUpdate;
end;

function TLearningListFrame.NewItemSelected: Boolean;
begin
  NewItemSelected := DataListBox.ItemIndex >= DataListBox.Count - 1
end;

procedure TLearningListFrame.AddNewLearning;
var
  Lrn: TJSONObject;
begin
  if EditLearningForm.ShowLearningEdit(Db) then begin
    Lrn := TJSONObject.Create;
    Lrn.Add('level', EditLearningForm.SelectedLevel);
    Lrn.Add('skillId', EditLearningForm.SelectedSkillId);
    Lrn.Add('note', EditLearningForm.SelectedNote);

    EditedLearnings.Add(Lrn);

    DataListBox.Items.BeginUpdate;
    DataListBox.Items[DataListBox.Items.Count - 1] := FormatLearning(Lrn);
    DataListBox.Items.Add(AddNewLearningStr);
    DataListBox.Items.EndUpdate;
  end
end;

procedure TLearningListFrame.EditSelectedLearning;
var
  Lrn: TJSONObject;
  LevelJson, SkillIdJson: TJSONNumber;
  NoteJson: TJSONString;
  Level: Integer = 0;
  SkillId: Integer = 0;
  Note: String = '';
begin
  Lrn := EditedLearnings.Objects[DataListBox.ItemIndex];
  if Lrn.Find('level', LevelJson) then
    Level := LevelJson.AsInteger;
  if Lrn.Find('skillId', SkillIdJson) then
    SkillId := SkillIdJson.AsInteger;
  if Lrn.Find('note', NoteJson) then
    Note := NoteJson.AsString;

  if EditLearningForm.ShowLearningEdit(Db, Level, SkillId, Note) then begin
    Lrn.Integers['level'] := EditLearningForm.SelectedLevel;
    Lrn.Integers['skillId'] := EditLearningForm.SelectedSkillId;
    Lrn.Strings['note'] := EditLearningForm.SelectedNote;
    DataListBox.Items[DataListBox.ItemIndex] := FormatLearning(Lrn);
  end
end;

procedure TLearningListFrame.SetDatabase(ADb: TDatabase);
begin
  Db := ADb
end;

procedure TLearningListFrame.SetEditedLearnings(AEditedLearnings: TJSONArray);
begin
  EditedLearnings := AEditedLearnings;
  UpdateList
end;

end.

